home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Mark.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-05
|
5KB
|
259 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Mark.h"
#include "Class.h"
#include "OrdColl.h"
#include "Math.h"
//---- Mark --------------------------------------------------------------------
NewMetaImpl(Mark,Object, (T(pos), T(len), T(state)));
Mark::Mark(int p, int l, eMarkState s, eMarkFlags flags)
{
pos= p;
len= l;
state= s;
if ((flags & eMarkInclStart) == eMarkInclStart)
SetFlag(eMarkInclStart);
if ((flags & eMarkFixedSize) == eMarkFixedSize)
SetFlag(eMarkFixedSize);
if ((flags & eMarkLocked) == eMarkLocked)
SetFlag(eMarkLocked);
}
Mark::Mark(Mark *m)
{
pos= m->pos;
len= m->len;
state= m->state;
}
int Mark::Compare(Object *op)
{
return (pos - ((Mark*)op)->pos);
}
bool Mark::HasChanged (int start,int l)
{
return (state != eStateNone || pos != start || len != l);
}
OStream &Mark::PrintOn(OStream& s)
{
Object::PrintOn(s);
return s << pos SP << len SP << state SP;
}
IStream &Mark::ReadFrom(IStream& s)
{
Object::ReadFrom(s);
return s >> pos >> len >> Enum(state);
}
Object *Mark::deepclone()
{
if (IsA() == Meta(Mark))
return new Mark(pos, len, (eMarkState)state);
return 0;
}
void Mark::Cut(int at, int n)
{
if (at < 0)
n+= at;
at= Math::Max(0, at);
// the different cases are shown as: '|' = mark positions '^' deleted range
if (TestFlag(eMarkLocked))
return;
if (TestFlag(eMarkFixedSize)) {
// ^ | | ^ includes ^ | ^|
if (at <= pos && at + n >= pos + len) {
state= eStateDeleted;
len= 0;
pos= at;
}
// ^ ^ | | includes ^ ^| |
else if (at + n <= pos) {
pos-= n;
}
// | | ^ ^ includes | |^ ^
else if (at >= pos + len)
;
// ^ | ^ |, | ^ | ^,| ^ ^ | includes |^ ^|
else
Error("Cut", "should not occur");
} else {
// | ^ ^ | includes |^ ^|
if (at >= pos && at + n <= pos + len) { // contained
state= eStateChanged;
len-= n;
}
// ^ | | ^ includes ^ | ^|
else if (at < pos && at + n >= pos + len) {
state= eStateDeleted;
len= 0;
pos= at;
}
// ^ | ^ |
else if (at < pos && at + n > pos) {
len= pos+len - (at +n);
pos= at;
state= eStateChanged;
}
// | ^ | ^
else if (at >= pos && at < pos + len) {
len= at - pos;
state= eStateChanged;
}
// ^ ^ | | includes ^ ^| |
else if (at + n <= pos)
pos-= n;
// | | ^ ^ includes | |^ ^
else if (at >= pos + len)
;
else
Error("Cut", "should not occur");
}
}
void Mark::Paste(int at, int n)
{
n= Math::Max(0, n);
at= Math::Max(0, at);
if (TestFlag(eMarkLocked))
return;
if ((at > pos || (TestFlag(eMarkInclStart) && at == pos)) && at < pos + len){
state= eStateChanged;
len += n;
} else if (at < pos || (!TestFlag(eMarkInclStart) && at == pos))
pos += n;
}
void Mark::Change(int at, int n)
{
if (TestFlag(eMarkLocked))
return;
if (at < pos && at+n >= pos+len)
state= eStateChanged;
else if (at >= pos && at < pos+len)
state= eStateChanged;
else if (at+n >= pos && at+n < pos+len)
state= eStateChanged;
}
//---- MarkList ----------------------------------------------------------------
NewMetaImpl(MarkList,Object, (TP(marks), TB(doRemove)));
MarkList::MarkList(bool remove, SeqCollection *rep)
{
doRemove= remove;
if (rep)
marks= rep;
else
marks= new OrdCollection;
}
MarkList::~MarkList()
{
if (doRemove)
marks->FreeAll();
SafeDelete(marks);
}
void MarkList::Add(Mark *m)
{
marks->Add(m);
}
Mark *MarkList::Remove(Mark *m)
{
return (Mark*)marks->Remove(m);
}
Mark *MarkList::At(int i)
{
return (Mark*)marks->At(i);
}
Iterator *MarkList::MakeIterator()
{
return marks->MakeIterator();
}
void MarkList::FreeAll()
{
return marks->FreeAll();
}
int MarkList::Size()
{
return marks->Size();
}
void MarkList::Empty()
{
return marks->Empty(marks->Size());
}
void MarkList::Replace(int from, int to, int sz)
{
Iter next(marks);
Mark *m;
int n= to-from;
while (m= (Mark*)next()) {
if(from != to) {
m->Cut(from, n);
if (doRemove && m->state == eStateDeleted) {
marks->Remove(m);
m->FreeAll();
delete m;
}
}
if (sz)
m->Paste(from, sz);
}
}
void MarkList::RangeChanged(int at,int n)
{
Iter next(marks);
Mark *m;
n= Math::Max(0, n);
at= Math::Max(0, at);
while (m= (Mark*) next())
m->Change(at, n);
}
OStream& MarkList::PrintOn (OStream&s)
{
Object::PrintOn(s);
return s << doRemove << marks SP;
}
IStream& MarkList::ReadFrom(IStream &s)
{
Object::ReadFrom(s);
return s >> Bool(doRemove) >> marks;
}